Linker

  • Linking in C++

    • Errors starting with C: Compiler Error

    • Errors starting with LNK: Linker Error

    • Many examples of errors caused by Compiler vs Linker.

    • Examples of how static  and inline  interact with #include .

    • Last example shows linking via header files.

Static Linker

  • .lib

    • Is the MSVC library format.

    • Can be a Static Library or an Import Library.

    • Static Library (.lib) :

      • Contains compiled object code that is statically linked into the final executable.

      • All code and data from the library are copied into the executable at build time.

      • The resulting executable does not depend on the .lib  file at runtime.

      • Used when you want everything in one binary without external dependencies.

    • Import Library (.lib) :

      • Provides symbols for linking against a DLL (Dynamic Link Library).

      • Contains only symbol references, not actual code.

      • The executable will require the corresponding .dll  file at runtime.

      • Used when linking against DLLs. The linker uses the .lib  to resolve symbols, but the actual code resides in the .dll .

    • You can determine whether a .lib  is static or import:

      • If it's paired with a .dll , it's likely an import library.

      • If there's no .dll , or the .lib  is explicitly intended for static linking, then it's a static library.

  • .a

    • Is the GCC/MinGW library format.

  • .o

Dynamic Linker

  • Linux:

    • .so

  • Windows:

    • .dll

  • Mac

    • .dylib

For Windows
  • Dynamic linking on Windows has 2 parts. The .lib  which has the symbols the linker needs & the .dll  (dynamic-link library) which has the binary data to OS needs to load at application start-up.

  • Unlike Unix-likes, there's no standard place for user binaries to live. Instead Windows searches next to the .exe  or where its manifest file tells it to (and few other places, but you don't normally put user binaries there). And searching next to the .lib  isn't portable.

  • A .lib  is used, in this case indicating an import library .

    • It tells the linker what symbols will be resolved at runtime and records the DLL name, but it does not contain the DLL binary or an absolute path to it.

    • Contains symbol stubs + DLL name, not the implementation.

    • The real code lives in .dll .

  • At program start the OS loader looks for the .dll  using the standard DLL search order (exe directory first, then system dirs, then PATH, etc.). If it cannot find a matching DLL (or a dependent DLL of that DLL), the process will fail to start or crash.

    • "You can change the folder with a  few sxs manifest files & passing linker flags but it's not worth the effort compared to a build script imo".

  • In Odin: foreign import  always links to .lib , and not to .dll .

"I'm getting no messages if incorrectly linked"
  • There's actually a message, but not when launched from some apps, like VSCode, due the way it's launched.

  • The error message pops up as an actual separate window that vscode seems to just swallow. Running from a separate terminal will fix it.

    • Nah, it didn't really worked.

Getting the Import Table

  • objdump -p demo.exe

    • GNU binutils / MinGW / MSYS2.

    • objdump -p demo.exe | findstr DLL

      • My favorite one.

  • llvm-objdump -p demo.exe

    • LLVM.

  • dumpbin /DEPENDENTS demo.exe

    • Visual Studio.

  • ntldd demo.exe

    • Linux tool for Window .exe .

  • You can use | grep DLL  or | findstr DLL  as text filter.

    • For windows, use findstr .